package com.cloud.job.utils;

import com.cloud.api.domain.job.DriveMotorData;
import com.cloud.api.domain.job.SubSystemTemperature;
import com.cloud.api.domain.job.SubSystemVoltageData;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author 杨斌
 * 2024-12-2024-12-12
 */
@Slf4j
public class JsonUtils {

    private JsonUtils(){}

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
//    static {
//        OBJECT_MAPPER.registerModule(new JavaTimeModule());
//        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//    }

    public static ObjectNode readObjectNode(String message) throws Exception {
        return (ObjectNode) OBJECT_MAPPER.readTree(message);
    }


    // 添加一个方法来将 JSON 字符串转换为对象
    public static <T> T readValue(String content, Class<T> valueType) {
        try {
            return OBJECT_MAPPER.readValue(content, valueType);
        } catch (Exception e) {
            throw new RuntimeException("Failed to read value from JSON", e);
        }
    }
    // 添加一个方法来将对象转换为 JSON 字符串
    public static String writeValueAsString(Object value) {
        try {
            return OBJECT_MAPPER.writeValueAsString(value);
        } catch (Exception e) {
            throw new RuntimeException("Failed to write value as JSON", e);
        }
    }


    public static String getTextValue(JsonNode node, String... path) {
        for (String p : path) {
            if (node == null || !node.has(p)) return null;
            node = node.get(p);
        }
        return node != null ? node.asText() : null;
    }
    public static Integer getIntValue(JsonNode node, String... path) {
        for (String p : path) {
            if (node == null || !node.has(p)) {
//                log.info("Node is null or does not have path: " + p);
                return null;
            }
            node = node.get(p);
        }
        return node != null ? node.asInt() : null;
    }
    public static Long getLongValue(JsonNode node, String... path) {
        for (String p : path) {
            if (node == null || !node.has(p)) return null;
            node = node.get(p);
        }
        return node != null ? node.asLong() : null;
    }
    public static Boolean getBooleanValue(JsonNode node, String... path) {
        for (String p : path) {
            if (node == null || !node.has(p)) return false;
            node = node.get(p);
        }
        return node != null ? node.asBoolean() : false;
    }
    public static Short getShortValue(JsonNode node, String... path) {
        Integer intValue = getIntValue(node, path);
        return intValue != null ? intValue.shortValue() : null;
    }
    public static JsonNode getNestedNode(JsonNode node, String... path) {
        for (String p : path) {
            if (node == null || !node.has(p)) {
                // 添加日志记录
//                log.error("Node is null or does not have path: " + p);
                return null;
            }
            node = node.get(p);
        }
        return node;
    }
    public static List<Long> getLongListValue(JsonNode node, String... path) {
        JsonNode arrayNode = getNestedNode(node, path);
        if (arrayNode == null || !arrayNode.isArray()) {
            return Collections.emptyList();
        }
        List<Long> result = new ArrayList<>();
        for (JsonNode item : arrayNode) {
            if (item.isNumber()) {
                result.add(item.asLong());
            }
        }
        return result;
    }
    public static List<SubSystemVoltageData> getSubSystemVoltageDataList(JsonNode node, String... path) {
        JsonNode arrayNode = getNestedNode(node, path);
        if (arrayNode == null || !arrayNode.isArray()) {
            return Collections.emptyList();
        }
        List<SubSystemVoltageData> result = new ArrayList<>();
        for (JsonNode item : arrayNode) {
            if (item.isObject()) {
                SubSystemVoltageData voltageData = new SubSystemVoltageData();
                voltageData.setNum(getShortValue(item, "num"));
                voltageData.setVoltage(getIntValue(item, "voltage"));
                voltageData.setCurrent(getIntValue(item, "current"));
                voltageData.setCellCount(getIntValue(item, "cellCount"));
                voltageData.setBatteryNumber(getIntValue(item, "batteryNumber"));
                voltageData.setBatteryCount(getShortValue(item, "batteryCount"));
                JsonNode cellVoltagesNode = item.get("cellVoltages");
                if (cellVoltagesNode != null && cellVoltagesNode.isArray()) {
                    List<Integer> cellVoltages = new ArrayList<>();
                    for (JsonNode voltageNode : cellVoltagesNode) {
                        if (voltageNode.isNumber()) {
                            cellVoltages.add(voltageNode.asInt());
                        }
                    }
                    voltageData.setCellVoltages(cellVoltages);
                } else {
                    voltageData.setCellVoltages(null);
                }

                result.add(voltageData);
            }
        }
        return result;
    }
    public static Map<String, Integer> getStartOffsetMap(JsonNode node, String... path) {
        JsonNode startOffsetNode = getNestedNode(node, path);
        if (startOffsetNode == null || !startOffsetNode.isObject()) {
            return Collections.emptyMap();
        }
        Map<String, Integer> result = new HashMap<>();
        startOffsetNode.fields().forEachRemaining(entry -> {
            result.put(entry.getKey(), entry.getValue().asInt());
        });
        return result;
    }
    public static List<DriveMotorData> getDriveMotorDataList(JsonNode node, String... path) {
        JsonNode arrayNode = getNestedNode(node, path);
        if (arrayNode == null || !arrayNode.isArray()) {
            return Collections.emptyList();
        }
        List<DriveMotorData> result = new ArrayList<>();
        for (JsonNode item : arrayNode) {
            if (item.isObject()) {
                DriveMotorData motorData = new DriveMotorData();
                motorData.setNum(getShortValue(item, "num"));
                motorData.setStatus(getShortValue(item, "status"));
                motorData.setControllerTemperature(getShortValue(item, "controllerTemperature"));
                motorData.setSpeed(getIntValue(item, "speed"));
                motorData.setTorque(getIntValue(item, "torque"));
                motorData.setTemperature(getShortValue(item, "temperature"));
                motorData.setControllerInputVoltage(getIntValue(item, "controllerInputVoltage"));
                motorData.setControllerBusCurrent(getIntValue(item, "controllerBusCurrent"));
                result.add(motorData);
            }
        }
        return result;
    }
    public static List<SubSystemTemperature> getSubSystemTemperatureList(JsonNode node, String... path) {
        JsonNode arrayNode = getNestedNode(node, path);
        if (arrayNode == null || !arrayNode.isArray()) {
            return Collections.emptyList();
        }
        List<SubSystemTemperature> result = new ArrayList<>();
        for (JsonNode item : arrayNode) {
            if (item.isObject()) {
                SubSystemTemperature temperature = new SubSystemTemperature();
                temperature.setNum(getShortValue(item, "num"));
                temperature.setTemperatureProbeCount(getIntValue(item, "temperatureProbeCount"));

                JsonNode probeTemperaturesNode = item.get("probeTemperatures");
                if (probeTemperaturesNode != null && probeTemperaturesNode.isArray()) {
                    List<Short> probeTemperatures = new ArrayList<>();
                    for (JsonNode tempNode : probeTemperaturesNode) {
                        if (tempNode.isNumber()) {
                            probeTemperatures.add((short) tempNode.asInt());
                        }
                    }
                    temperature.setProbeTemperatures(probeTemperatures);
                } else {
                    temperature.setProbeTemperatures(null);
                }

                result.add(temperature);
            }
        }
        return result;
    }
    public static List<Short> getProbeTemperatureList(JsonNode node, String... path) {
        JsonNode arrayNode = getNestedNode(node, path);
        if (arrayNode == null || !arrayNode.isArray()) {
            return Collections.emptyList();
        }
        List<Short> result = new ArrayList<>();
        for (JsonNode item : arrayNode) {
            if (item.isNumber()) {
                result.add((short) item.asInt());
            }
        }
        return result;
    }
    public static List<String> getStringListValue(JsonNode node, String... path) {
        JsonNode arrayNode = getNestedNode(node, path);
        if (arrayNode == null || !arrayNode.isArray()) {
            return Collections.emptyList();
        }
        List<String> result = new ArrayList<>();
        for (JsonNode item : arrayNode) {
            if (item.isTextual()) {
                result.add(item.asText());
            }
        }
        return result;
    }
    /**
     *  将列表转换为JSON字符串
     * @param list
     * @return
     * @param <T>
     */
    public static <T> String listToJson(List<T> list) {
        try {
            return OBJECT_MAPPER.writeValueAsString(list);
        } catch (Exception e) {
//            log.error("Failed to convert list to JSON string", e);
            return null;
        }
    }

    public static <K, V> String mapToJson(Map<K, V> map) {
        try {
            return OBJECT_MAPPER.writeValueAsString(map);
        } catch (Exception e) {
//            log.error("Failed to convert map to JSON string", e);
            return null;
        }
    }
}
